package shun.demo.remote.display.server;

import android.content.Context;
import android.os.SystemClock;
import android.util.Log;
import shun.demo.remote.display.model.Movement;
import shun.demo.remote.display.model.Point;
import shun.demo.remote.display.model.Property;
import shun.demo.remote.display.model.TimeSync;

import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.HashMap;

/**
 * Created by chen on 14-5-9.
 */
public class Clients {

    private HashMap<Socket, ObjectOutputStream> mSockets;
    private static Clients sInstance;

    // TODO: 考虑设备断开
    private int mScreenWidth;

    private Clients(Context context) {
        mSockets = new HashMap<Socket, ObjectOutputStream>(Config.MAX_CLIENTS);
    }

    public void send(Property p) {
        for (Socket socket : mSockets.keySet()) {
            if (socket == p.getFrom()) {
                continue;
            }
            try {
                ObjectOutputStream oos = mSockets.get(socket);
                oos.writeObject(p);
                Log.i(Config.LOG_TAG, "send\n" + p + " to: " + socket);
            } catch (IOException e) {
                // TODO delete the client
                e.printStackTrace();
            }
        }
    }

    public void forwardMovement(Movement movement) {
        for (Socket socket : mSockets.keySet()) {
            if (socket == movement.getFrom()) {
                continue;
            }
            try {
                ObjectOutputStream oos = mSockets.get(socket);
                oos.writeObject(movement);
                Log.i(Config.LOG_TAG, "forward\n" + movement + " to: " + socket);
            } catch (IOException e) {
                // TODO delete the client
                e.printStackTrace();
            }
        }
    }

    public ObjectOutputStream getObjectOutputStream(Socket socket) {
        return mSockets.get(socket);
    }

    public void add(Socket socket) {
        OutputStream os = null;
        try {
            os = socket.getOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(os);
            mSockets.put(socket, oos);
            Log.v(Config.LOG_TAG, "add client: " + socket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void delete(Socket socket) {
        mSockets.remove(socket);
        Log.v(Config.LOG_TAG, "delete client: " + socket);
    }

    public void handScreenSync(Point point, Socket socket) {
        mScreenWidth += point.getX();
        point.setX(mScreenWidth - point.getX());
        ObjectOutputStream oos = getObjectOutputStream(socket);
        try {
            oos.writeObject(point);
            Log.i(Config.LOG_TAG, "screenSync\n" + point + " to: " + socket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void handleTimeSync(TimeSync timeSync, Socket socket) {
        timeSync.setT1(SystemClock.uptimeMillis());
        ObjectOutputStream oos = getObjectOutputStream(socket);
        try {
            timeSync.setT2(SystemClock.uptimeMillis());
            oos.writeObject(timeSync);
            Log.i(Config.LOG_TAG, "timeSync\n" + timeSync + " to: " + timeSync.getFrom());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
